#include "RTC_calendar.h"
#include "parameters.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_rtc.h"
#include "stm32f4xx_hal_rtc_ex.h"
#include "stm32f429xx.h"

RTC_HandleTypeDef RtcHandle;
RTC_DateTypeDef  date;
RTC_TimeTypeDef  time;
uint32_t dateTimeNext;


static void RTC_CalendarConfig(void);
void RTC_AlarmConfig(void);

#define RTC_START_YEAR		14
#define RTC_START_MONTH		1
#define RTC_START_DATE		1
#define RTC_START_WERKDAY	4
#define RTC_START_HOUR		00
#define RTC_START_MIN		00
#define RTC_START_SEC		0

void RTC_CalendarInit(void)
{
	RtcHandle.Instance = RTC;
	RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
	RtcHandle.Init.AsynchPrediv = 0x7F;
	RtcHandle.Init.SynchPrediv = 0xFF;
	RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
	RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

	if(HAL_RTC_Init(&RtcHandle) != HAL_OK)
	{
		/* Initialization Error */
		Error_Handler();
	}

	/* Read the Back Up Register 0 Data */
	if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)
	{
		/* Configure RTC Calendar */
		RTC_CalendarConfig();
	}
	else
	{
		/* Check if the Power On Reset flag is set */
		if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
		{
			/* Turn on LED2: Power on reset occurred */
		}
		/* Check if Pin Reset flag is set */
		if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
		{
			/* Turn on LED4: External reset occurred */
		}
		/* Clear source Reset Flag */
		__HAL_RCC_CLEAR_RESET_FLAGS();
	}
}

/**
 * @brief  Configure the current time and date.
 * @param  None
 * @retval None
 */
static void RTC_CalendarConfig(void)
{
	RtcHandle.Instance = RTC;
	RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
	RtcHandle.Init.AsynchPrediv = 0x7F;
	RtcHandle.Init.SynchPrediv = 0x00FF;
	RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
	RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

	if(HAL_RTC_Init(&RtcHandle) != HAL_OK)
	{
		/* Initialization Error */
		Error_Handler();
	}

	date.Year = RTC_START_YEAR;
	date.Month = RTC_START_MONTH;
	date.Date = RTC_START_DATE;
	date.WeekDay = RTC_START_WERKDAY;
	time.Hours = RTC_START_HOUR;
	time.Minutes = RTC_START_MIN;
	time.Seconds = RTC_START_SEC;
	time.TimeFormat = RTC_HOURFORMAT_24;
	time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	time.StoreOperation = RTC_STOREOPERATION_RESET;

	if(HAL_RTC_SetDate(&RtcHandle,&date,RTC_FORMAT_BCD) != HAL_OK)
		Error_Handler();

	if(HAL_RTC_SetTime(&RtcHandle,&time,RTC_FORMAT_BCD) != HAL_OK)
		Error_Handler();
}


eReturn AlarmCheck(void)
{
	RTC_AlarmTypeDef alarm;
	HAL_RTC_GetDate(&RtcHandle, &date, RTC_FORMAT_BCD);
	HAL_RTC_GetTime(&RtcHandle, &time, RTC_FORMAT_BCD);
	HAL_RTC_GetAlarm(&RtcHandle, &alarm, RTC_ALARM_A, RTC_FORMAT_BCD);

	if((alarm.AlarmTime.Seconds <= time.Seconds ) ||
			(alarm.AlarmTime.Minutes < time.Minutes))
		return E_EROR;
	else
		return E_OK;
}

void RTC_Set_Next_Time(void)
{
	dateTimeNext = (startParam.poll_interval[0] * 3600);
	dateTimeNext += (startParam.poll_interval[1] * 60);
	dateTimeNext += (startParam.poll_interval[2]);
}

void RTC_AlarmConfig(void)
{
	RTC_AlarmTypeDef alarm;
	HAL_RTC_GetDate(&RtcHandle, &date, RTC_FORMAT_BCD);
	HAL_RTC_GetTime(&RtcHandle, &time, RTC_FORMAT_BCD);

	alarm.Alarm = RTC_ALARM_A;
	alarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	alarm.AlarmMask = RTC_ALARMMASK_ALL;
	alarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
	alarm.AlarmTime.TimeFormat = RTC_HOURFORMAT_24;;
	alarm.AlarmTime.SubSeconds = 0;
	if(HAL_RTC_SetAlarm_IT(&RtcHandle, &alarm, RTC_FORMAT_BCD) != HAL_OK)
		Error_Handler();
	HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
